package com.gitee.wsl.struct.command.model.parameters.groups

import com.gitee.wsl.struct.command.model.command.BaseCliktCommand
import com.gitee.wsl.struct.command.context.Context
import com.gitee.wsl.struct.command.output.HelpFormatter
import com.gitee.wsl.struct.command.model.parameters.BaseOption
import com.gitee.wsl.struct.command.model.parameters.BaseOptionDelegate
import com.gitee.wsl.struct.command.model.parameters.options.Option
import com.gitee.wsl.struct.command.parsers.OptionInvocation

interface ParameterGroup:
    BaseOption<Map<Option, List<OptionInvocation>>, HelpFormatter.ParameterHelp.Group?> {
    /**
     * The name of the group, or null if parameters in the group should not be separated from other
     * parameters in the help output.
     */
    val groupName: String?

    /**
     * A help message to display for this group.
     *
     * If [groupName] is null, the help formatter will ignore this value.
     */
    val groupHelp: String?

    override fun help(context: Context): String = groupHelp?:""

    override val helpTags: Map<String, String>
        get() = emptyMap()

    override fun parameterHelp(context: Context): HelpFormatter.ParameterHelp.Group? {
        val n = groupName
        val h = groupHelp
        return if (n == null || h == null) null else HelpFormatter.ParameterHelp.Group(n, h)
    }

    /**
     * Called after this command's argv is parsed and all options are validated to validate the group constraints.
     *
     * @param context The context for this parse
     * @param invocationsByOption The invocations of options in this group.
     */
    //fun finalize(context: Context, invocationsByOption: Map<Option, List<OptionInvocation>>)

    /**
     * Called after all of a command's parameters have been [finalize]d to perform validation of the final values.
     */
    //fun postValidate(context: Context)
}

/** A [ParameterGroup] that can be used as a property delegate */
/*interface ParameterGroupDelegate<out T> :
    ParameterGroup,
    ReadOnlyProperty<BaseCliktCommand<*>, T>,
    PropertyDelegateProvider<BaseCliktCommand<*>, ReadOnlyProperty<BaseCliktCommand<*>, T>> {
    *//** Implementations must call [BaseCliktCommand<*>.registerOptionGroup] *//*
    override operator fun provideDelegate(
        thisRef: BaseCliktCommand<*>,
        property: KProperty<*>,
    ): ReadOnlyProperty<BaseCliktCommand<*>, T>
}*/


interface ParameterGroupDelegate<out T> :
    ParameterGroup,
    BaseOptionDelegate<Map<Option, List<OptionInvocation>>, HelpFormatter.ParameterHelp.Group?, BaseCliktCommand<*>, T>

